// 这不就是最长直径吗？
// 只不过直径的权重是1
#include <iostream>
#include <algorithm>
#include <cstring>
#include <unordered_map>

using namespace std;
using LL = long long;
const int N = 50010;
int n;
LL fsum[N];
int e[N], ne[N], h[N], idx, ans;
bool st[N];

void add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

LL get_ysum(int x)
{
    int tmp = x;
    unordered_map<int, int> cnts;
    for (int i = 2; i <= x / i; ++i)
    {
        int num = 0;
        while (x % i == 0) x /= i, ++num;
        if (num) cnts[i] = num;
    }
    if (x > 1) cnts[x] = 1;
    LL ans = 1;
    for (auto& [k, v] : cnts)
    {
        LL t = 1;
        while (v--) t = t * k + 1;
        ans = ans * t;
    }
    ans -= tmp;
    return ans;
}

// 找到距离根节点最远的叶子节点
int dfs(int u)
{
    st[u] = true;

    int dist = 0;
    int d1 = 0, d2 = 0;
    for (int i = h[u]; ~i; i = ne[i])
    {
        int j = e[i];
        if (!st[j])
        {
            int d = dfs(j);
            dist = max(dist, d);
            if (d >= d1) d2 = d1, d1 = d;
            else if (d > d2) d2 = d;
        }
    }

    ans = max(ans, d1 + d2);

    return dist + 1;
}


int main()
{
    cin >> n;
    memset(h, -1, sizeof h);
    for (int i = 1; i <= n; i++)
        for (int j = 2; j <= n / i; j++)
            fsum[i * j] += i;


    for (int i = 2; i <= n; ++i)
    {
        // 找到约数之和
        int ret = fsum[i];
        if (ret <= i)
            add(ret, i);
    }



    for (int i = 1; i <= n; ++i)
        if (!st[i])
            dfs(i);
    cout << ans << endl;
    // 
    // dfs(u, -1, 0, max_depth, nd);
    // max_depth = 0;
    // dfs(nd, -1, 0, max_depth, nd);
    // cout << max_depth << endl;
    return 0;
}